package ac.github.oa.internal.core.attribute

import ac.github.oa.api.common.Matcher
import taboolib.common5.Coerce
import java.util.regex.Pattern
import kotlin.math.max
import kotlin.math.min

fun AttributeData.loadTo(attribute: Attribute, string: String) {
    attribute.toEntities().forEach {
        getData(attribute.getPriority(), it.index).loadTo(it, string)
    }
}

fun Attribute.Entry.isIgnore(string: String): Boolean {
    return ignores.any { string.contains(it) }
}

fun AttributeData.Data.loadTo(entry: Attribute.Entry, string: String) {

    if (entry.keywords.any { it in string } && !entry.isIgnore(string)) {
        when (entry.type) {

            Attribute.Type.SINGLE -> add(0, Matcher.single(string).toDouble())

            Attribute.Type.RANGE -> Matcher.range(string).let {
                add(0, it.min)
                add(1, it.max)
            }

            Attribute.Type.PERCENT -> {
                if (string.contains('%')) {
                    add(0, Matcher.single(string).amount)
                }
            }
        }
    }
}

val FILTER_RULES = listOf(
    Regex("§+[a-z0-9%]"),
    Regex("[^0-9+--.]"),
)

fun getNumber(string: String): String {
    var prey = string
    FILTER_RULES.forEach { prey = prey.replace(it, "") }
    return prey.ifEmpty { "0.0" }
}

fun AttributeData.Data.correct(entry: Attribute.Entry) {
    val correctRules = entry.corrects
    if (correctRules.isEmpty()) {
        this.array.forEachIndexed { index, d ->
            if (correctRules.size > index) {
                set(index, min(max(d, correctRules[index][1]), correctRules[index][0]))
            }
        }
    }
}


fun Attribute.Entry.getRoot() = (node as AbstractAttribute).root


fun AttributeData.getAttribute(index: Int): Attribute {
    return AttributeManager.usableAttributes[index] ?: error("[AttributeManager] $index not found.")
}

fun Attribute.toEntities(): List<Attribute.Entry> {
    return (this as AbstractAttribute).entries
}

fun Attribute.includesType(attributeType: AttributeType): Boolean {
    val types = (this as AbstractAttribute).types
    return types.indexOf(attributeType) != -1
}
